#!/usr/bin/env python3
import os
import subprocess
import sys
from typing import List, Optional

def clear_screen():
    """清空终端屏幕"""
    os.system('cls' if os.name == 'nt' else 'clear')

def print_menu():
    """打印主菜单"""
    clear_screen()
    print("""
    ██████╗  ██████╗  ██████╗██╗  ██╗███████╗██████╗ 
    ██╔══██╗██╔═══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗
    ██║  ██║██║   ██║██║     █████╔╝ █████╗  ██████╔╝
    ██║  ██║██║   ██║██║     ██╔═██╗ ██╔══╝  ██╔══██╗
    ██████╔╝╚██████╔╝╚██████╗██║  ██╗███████╗██║  ██║
    ╚═════╝  ╚═════╝  ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝
    """)
    print("Docker 管理工具 v1.0")
    print("="*50)
    print("1. 列出所有容器")
    print("2. 列出运行中的容器")
    print("3. 列出所有镜像")
    print("4. 启动/停止/重启容器")
    print("5. 进入容器终端")
    print("6. 查看容器日志")
    print("7. 删除容器")
    print("8. 删除镜像")
    print("9. 清理无用资源")
    print("10. 构建镜像")
    print("11. 查看Docker系统信息")
    print("12. 查看Docker磁盘使用情况")
    print("0. 退出")
    print("="*50)

def run_command(cmd: str, capture_output: bool = False) -> Optional[str]:
    """执行shell命令并返回输出"""
    try:
        if capture_output:
            result = subprocess.run(cmd, shell=True, check=True, 
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                  text=True)
            return result.stdout
        else:
            subprocess.run(cmd, shell=True, check=True)
            return None
    except subprocess.CalledProcessError as e:
        print(f"命令执行失败: {e}")
        if capture_output:
            print(f"错误输出: {e.stderr}")
        return None

def list_containers(all: bool = False):
    """列出容器"""
    cmd = "docker ps --format 'table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Names}}'"
    if all:
        cmd += " -a"
    output = run_command(cmd, capture_output=True)
    if output:
        print(output)

def list_images():
    """列出镜像"""
    cmd = "docker images --format 'table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.Size}}'"
    output = run_command(cmd, capture_output=True)
    if output:
        print(output)

def manage_container():
    """管理容器状态"""
    list_containers(all=True)
    container_id = input("\n请输入容器ID或名称: ").strip()
    if not container_id:
        print("无效的容器ID/名称")
        return
    
    print("\n1. 启动容器")
    print("2. 停止容器")
    print("3. 重启容器")
    choice = input("请选择操作 (1-3): ").strip()
    
    if choice == "1":
        run_command(f"docker start {container_id}")
        print(f"容器 {container_id} 已启动")
    elif choice == "2":
        run_command(f"docker stop {container_id}")
        print(f"容器 {container_id} 已停止")
    elif choice == "3":
        run_command(f"docker restart {container_id}")
        print(f"容器 {container_id} 已重启")
    else:
        print("无效的选择")

def exec_container():
    """进入容器终端"""
    list_containers(all=True)
    container_id = input("\n请输入容器ID或名称: ").strip()
    if not container_id:
        print("无效的容器ID/名称")
        return
    
    print("\n1. 使用/bin/bash (适用于大多数Linux容器)")
    print("2. 使用/bin/sh (更基本的shell)")
    print("3. 自定义shell")
    choice = input("请选择shell类型 (1-3): ").strip()
    
    if choice == "1":
        shell = "/bin/bash"
    elif choice == "2":
        shell = "/bin/sh"
    elif choice == "3":
        shell = input("请输入自定义shell路径: ").strip()
    else:
        print("无效的选择，默认使用/bin/sh")
        shell = "/bin/sh"
    
    run_command(f"docker exec -it {container_id} {shell}")

def view_logs():
    """查看容器日志"""
    list_containers(all=True)
    container_id = input("\n请输入容器ID或名称: ").strip()
    if not container_id:
        print("无效的容器ID/名称")
        return
    
    print("\n1. 查看实时日志")
    print("2. 查看最后N行日志")
    print("3. 查看完整日志")
    choice = input("请选择日志查看方式 (1-3): ").strip()
    
    if choice == "1":
        run_command(f"docker logs -f {container_id}")
    elif choice == "2":
        lines = input("请输入要显示的行数 (默认100): ").strip() or "100"
        run_command(f"docker logs --tail {lines} {container_id}")
    elif choice == "3":
        run_command(f"docker logs {container_id}")
    else:
        print("无效的选择")

def delete_container():
    """删除容器"""
    list_containers(all=True)
    container_id = input("\n请输入要删除的容器ID或名称: ").strip()
    if not container_id:
        print("无效的容器ID/名称")
        return
    
    force = input("是否强制删除? (y/N): ").strip().lower() == 'y'
    cmd = f"docker rm {'-f ' if force else ''}{container_id}"
    run_command(cmd)
    print(f"容器 {container_id} 已删除")

def delete_image():
    """删除镜像"""
    list_images()
    image_id = input("\n请输入要删除的镜像ID: ").strip()
    if not image_id:
        print("无效的镜像ID")
        return
    
    force = input("是否强制删除? (y/N): ").strip().lower() == 'y'
    cmd = f"docker rmi {'-f ' if force else ''}{image_id}"
    run_command(cmd)
    print(f"镜像 {image_id} 已删除")

def prune_system():
    """清理无用资源"""
    print("\n1. 清理停止的容器")
    print("2. 清理悬空镜像")
    print("3. 清理所有无用资源")
    print("4. 清理构建缓存")
    choice = input("请选择清理类型 (1-4): ").strip()
    
    if choice == "1":
        run_command("docker container prune")
    elif choice == "2":
        run_command("docker image prune")
    elif choice == "3":
        run_command("docker system prune")
    elif choice == "4":
        run_command("docker builder prune")
    else:
        print("无效的选择")

def build_image():
    """构建Docker镜像"""
    path = input("请输入Dockerfile所在目录路径 (默认当前目录): ").strip() or "."
    tag = input("请输入镜像标签 (如 myimage:latest): ").strip()
    if not tag:
        print("镜像标签不能为空")
        return
    
    cmd = f"docker build -t {tag} {path}"
    run_command(cmd)

def system_info():
    """查看Docker系统信息"""
    run_command("docker info")

def disk_usage():
    """查看Docker磁盘使用情况"""
    run_command("docker system df")

def main():
    while True:
        print_menu()
        choice = input("请选择操作 (0-12): ").strip()
        
        if choice == "0":
            print("感谢使用，再见！")
            break
        elif choice == "1":
            list_containers(all=True)
        elif choice == "2":
            list_containers(all=False)
        elif choice == "3":
            list_images()
        elif choice == "4":
            manage_container()
        elif choice == "5":
            exec_container()
        elif choice == "6":
            view_logs()
        elif choice == "7":
            delete_container()
        elif choice == "8":
            delete_image()
        elif choice == "9":
            prune_system()
        elif choice == "10":
            build_image()
        elif choice == "11":
            system_info()
        elif choice == "12":
            disk_usage()
        else:
            print("无效的选择，请重新输入")
        
        input("\n按Enter键继续...")

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("\n操作被用户中断")
        sys.exit(0)